package com.zyx.springmvcmsb.advanced.controller;

import com.zyx.springmvcmsb.advanced.exception.UsernameException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author zyx
 * @since 2021/10/6 16:50
 *
 * spring处理异常时有以下三种方法:
 *      1.使用 ExceptionHandlerExceptionResolver 处理 @ExceptionHandler 中的异常
 *      2.使用 ResponseStatusExceptionResolver 处理 @ResponseStatus 中自定义的异常
 *      3.使用 DefaultHandlerExceptionResolver 处理 SpringMVC 自带异常
 *
 * 实际过程中通常使用第一种方式用同一的自定义页面进行处理
 *
 * 当使用ExceptionHandler进行处理的时候, 默认会先走小范围, 然后再寻找大范围
 *      当在某一个类中定义的ExceptionHandler只能处理当前类的异常信息, 如果其他类包含的话, 无法进行处理
 *      可以通过@ControllerAdvice注解进行标注, 表示为全局异常处理类
 *      每次进行异常处理的时候, 现在本类查找, 然后去查找全局配置
 *
 */
@Controller
public class ExceptionController {

    @RequestMapping("/exception1")
    public String exception1() {
        System.out.println("=====>>>>> " + this.getClass().getName());
        int i = 1 / 0;
        return "success";
    }

    /**
     * `@ResponseStatus` 虽然可以标注在方法上，但是不推荐使用
     */
    @ResponseStatus(reason = "我就是错了，不知道什么原因", value = HttpStatus.OK)
    @RequestMapping("/exception2")
    public String exception2() {
        System.out.println("exception2");
        return "success";
    }

    @RequestMapping("/exception3")
    public String exception3(String username) {
        System.out.println("exception3");
        if ("admin".equals(username)) {
            return "success";
        } else {
            throw new UsernameException();
        }
    }

    /**
     * 使用 DefaultHandlerExceptionResolver 处理SpringMVC自带异常
     */
    @RequestMapping(value = "/exception4", method = RequestMethod.POST)
    public String exception4() {
        System.out.println("exception4");
        return "success";
    }

    // @ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
    // public ModelAndView handlerException(Exception exception) {
    //     System.out.println("exception1");
    //     ModelAndView mv = new ModelAndView();
    //     mv.setViewName("error");
    //     mv.addObject("ex", exception);
    //     return mv;
    // }
    //
    // @ExceptionHandler(value = {Exception.class})
    // public ModelAndView handlerException2(Exception exception) {
    //     System.out.println("exception2");
    //     ModelAndView mv = new ModelAndView();
    //     mv.setViewName("error");
    //     mv.addObject("ex", exception);
    //     return mv;
    // }

}
